//
//  PlayListManager.swift
//  音乐播放管理器
//  封装了常用的操作，播放这首音乐，下一曲，下一曲，循环模式等功能
//
//  Created by smile on 2019/4/14.
//  Copyright © 2019 ixuea. All rights reserved.
//

import Foundation

class PlayListManager {
    // 单例设计模式
    static var shared=PlayListManager()
    
    /// 播放列表
    var datum:[Song] = []
    
    /// 是否播放了
    var isPlay = false
    
    /// 当前播放的音乐
    var currentSong:Song?
    
    /// 播放管理器
    var musicPlayerManager:MusicPlayerManager=MusicPlayerManager.shared()
    
    /// 循环模式
    var model:MusicPlayerRepeatModel=MusicPlayerRepeatModel.list
    
    /// 数据库工具类
    var orm:ORMUtil=ORMUtil.shared()
    
    /// 下载器
//    var downloader:DownloadManager?
    
    /// 音乐循环状态
    ///
    /// - list: 列表循环
    /// - one: 单曲循环
    /// - random: 随机循环
    enum MusicPlayerRepeatModel:Int {
        case list = 0
        case one
        case random
    }
    
    
    /// 初始化
    init() {
        //设置播放完毕回调
        musicPlayerManager.onComplete = {
            data in
            //播放完毕
            if self.getLoopModel() == MusicPlayerRepeatModel.one {
                //单曲循环
                self.play(self.currentSong!)
            } else {
                //其他模式
                //就要播放下一首
                if let next = self.next() {
                    self.play(next)
                }
                
                
            }

        }
        
        //初始化的时候从数据库中获取播放列表
        initPlayList()
        
        //初始化监听器
        initListeners()
    }
    
    /// 从数据库中恢复播放列表
    func initPlayList() {
        //从数据库中查看播放列表
        let songs:[Song]=orm.queryPlayList(PreferenceUtil.userId()!)
        
        //删除原来的数据
        datum.removeAll()
        
        if songs.count>0 {
            datum = datum + songs
            
            //有播放列表才处理
            //获取当前播放的歌曲的Id
            let songId = PreferenceUtil.lastPlaySongId()
            
            if let songId = songId {
                //遍历所有歌曲找到上次播放的这首音乐
                for song in songs {
                    if song.id==songId{
                        currentSong=song
                        break
                    }
                    
                    if let currentSong=currentSong{
                        //找到了
                    }else{
                        //表示没找到，可能各种原因
                        defaultPlaySong()
                    }
                }
            }else{
                //如果没有最好播放音乐的Id
                //就默认为第一首
                defaultPlaySong()
            }
            
        }
        
    }
    
    /// 初始化监听器
    func initListeners() {
        
        
    }
    
    /// 默认播放音乐
    func defaultPlaySong() {
        currentSong=datum[0]
        
        //把初始化音乐设置到播放管理器
        //因为有些回调要返回当前音乐
        musicPlayerManager.data=currentSong!
    }

    /// 设置播放列表
    ///
    /// - Parameter data: <#data description#>
    func setPlayList(_ data:[Song]) {
        print("PlayListManager setPlayList")
        
        //将原来数据在PlayList的标志去掉
        //并保存到数据库
        DataUtil.changePlayListFlag(datum, false)
        saveAll()
        
        //删除数组中原来的数据
        datum.removeAll()
        
        //将当前传递进来的数据更改为在PlayList标志
        //并添加到集合
        datum = datum + data
        DataUtil.changePlayListFlag(datum, true)
        
        //保存到数据库
        saveAll()
    }
    
    /// 获取播放列表
    ///
    /// - Returns: <#return value description#>
    func getPlayList() -> [Song]? {
        print("PlayListManager getPlayList")
        return datum
    }
    
    /// 保存播放列表
    func saveAll() {
        //然后在保存当前所有数据
        for song in datum {
            //保存
            orm.saveSong(song, PreferenceUtil.userId()!)
        }
    }

    /// 播放
    ///
    /// - Parameter data: <#data description#>
    func play(_ song:Song) {
        isPlay=true
        currentSong=song
        
        var downloadInfo:DownloadInfo?
        
        //查询是否有本地下载完成的任务
        downloadInfo=DownloadManager.sharedInstance().findDownloadInfo(song.uri)
        if DownloadStatus.completed==downloadInfo?.status {
            //有下载完成的音乐
            //播放本地路径
            print("PlayListManager play offline:\(downloadInfo!.absolutePath())")
            musicPlayerManager.play(downloadInfo!.absolutePath(),song)
        }else{
            //播放在线地址
            print("PlayListManager play online:\(song.uri)")
            musicPlayerManager.play(ResourceUtil.resourceUri(song.uri),song)
        }
    }
    
    func play(_ position:Int) {
        print("PlayListManager play:\(position)")
        let song=getPlayList()![position]
        play(song)
    }

    /// 暂停
    func pause() {
        print("PlayListManager pause")
        musicPlayerManager.pause()
    }

    /// 继续播放
    func resume() {
        print("PlayListManager resume")
        if isPlay {
            //原来已经播放过
            //也就说播放器已经初始化了
            musicPlayerManager.resume()
        } else {
            //到这里，是应用开启后，第一次点继续播放
            //而这时内部其实还没有准备播放，所以应该调用播放
            play(currentSong!)
            
            if currentSong!.progress > 0 {
                //如果有播放进度就从该进度开始播放
                musicPlayerManager.seekTo(currentSong!.progress)
            }
            
        }
    }

    /// 从播放列表删除这一首音乐
    ///
    /// - Parameter data: <#data description#>
    func delete(_ data:Song) {
        if data.id == currentSong!.id {
            //如果删除的是当前播放歌曲
            //应该停止当前播放
            //并播放下一首音乐
            pause()
            
            let nextSong = next()!
            
            //只有获取的下一个条目不是自己才进行播放
            //因为自己要删除
            if nextSong.id == currentSong!.id{
                //没有歌曲可以播放了
                self.currentSong = nil
            }else{
                play(nextSong)
            }
        } else {
            //如果删除的不是正在播放的，就直接删除
        }
        
        let playListOC=datum as NSArray
        let index=playListOC.index(of: data)
        datum.remove(at: index)
        
        //从数据的播放列表中删除
        data.playList=false
        
        orm.saveSong(data, PreferenceUtil.userId()!)
    }

    /// 获取当前播放的音乐
    ///
    /// - Returns: <#return value description#>
    func getPlaySong() -> Song? {
        return currentSong
    }

    /// 获取上一首要播放的音乐
    ///
    /// - Returns:
    func previous() -> Song? {
        if datum.count==0 {
            return nil
        }
        
        switch model {
        case .random:
            //在0~datum.size()中，不包含datum.size()
            let i=Int(arc4random()) % datum.count
            let song=datum[i]
            return song
        default:
            let datumOC = datum as NSArray
            var index=datumOC.index(of: currentSong)
            if index != -1{
                //找到了
                //如果当前播放是列表第一个，那就从最后一个开始播放
                if (index == 0) {
                    index = datum.count - 1
                } else {
                    index -= 1
                }
            }else{
                //抛出异常
                //因为正常情况下是能找到的
            }
            
            print("PlayListManager previous:\(index)")
            
            return datum[index]
        }
    }
    
    /// 获取下一首要播放的音乐
    ///
    /// - Returns: <#return value description#>
    func next() -> Song? {
        if datum.count==0 {
            return nil
        }
        
        switch model {
        case .random:
            //在0~datum.size()中，不包含datum.size()
            let i=Int(arc4random()) % datum.count
            let song=datum[i]
            return song
        default:
            let datumOC = datum as NSArray
            var index=datumOC.index(of: currentSong)
            if index != -1{
                //找到了
                //如果当前播放是列表最后一个，那就从0开始播放
                if index==datum.count-1{
                    index = 0
                }else{
                    index += 1
                }
            }else{
                //抛出异常
                //因为正常情况下是能找到的
            }
            
            print("PlayListManager next:\(index)")
            
            return datum[index]
        }
    }


    /// 获取当前循环模式
    ///
    /// - Returns: <#return value description#>
    func getLoopModel() -> MusicPlayerRepeatModel {
        return model
    }

    /// 更改循环模式
    ///
    /// - Returns: <#return value description#>
    func changeLoopModel() -> MusicPlayerRepeatModel {
        var model=getLoopModel().rawValue
        
        //循环模式+1
        model += 1
        
        if model > MusicPlayerRepeatModel.random.rawValue {
            //如果当前循环模式
            //大于最后一个循环模式
            //就设置为第0个循环模式
            self.model = MusicPlayerRepeatModel(rawValue: 0)!
        } else {
            self.model = MusicPlayerRepeatModel(rawValue: model)!
        }
        
        if self.model==MusicPlayerRepeatModel.one {
            //循环模式，设置到播放管理器
            musicPlayerManager.setLooping(true)
        } else {
            //其他模式关闭循环
            musicPlayerManager.setLooping(false)
        }
        
        return self.model
        
    }

}
